package com.hbnu.system.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hbnu.system.config.BaseException;
import com.hbnu.system.constant.RoleConstant;
import com.hbnu.system.constant.StatusCheckConstant;
import com.hbnu.system.core.base.CommonPage;
import com.hbnu.system.mapper.ArtMapper;
import com.hbnu.system.model.context.BaseContext;
import com.hbnu.system.model.dto.ArtDTO;
import com.hbnu.system.model.dto.CheckBackDTO;
import com.hbnu.system.model.entity.*;
import com.hbnu.system.model.query.ArtPageQuery;
import com.hbnu.system.model.vo.ArtVO;
import com.hbnu.system.service.*;
import com.hbnu.system.utils.CheckAuditHelper;
import com.hbnu.system.utils.CheckRoleUtil;
import com.hbnu.system.utils.UserInfoUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ${author}
 * @since 2023-05-16
 */
@Service
public class ArtServiceImpl extends ServiceImpl<ArtMapper, Art> implements IArtService {

    @Autowired
    private IArtService iArtService;
    @Autowired
    private IUserService iUserService;
    @Autowired
    private AuditService auditService;
    @Autowired
    private IdToStatsService idToStatsService;
    @Autowired
    private IArtfileService artfileService;
    @Autowired
    private IArtauthorService artauthorService;
    @Autowired
    private IArtQualificationService artQualificationService;
    @Autowired
    private ArtMapper artMapper;
    @Autowired
    private CheckAuditHelper checkAuditHelper ;

    @Autowired
    private UserInfoUtils userInfoUtils;

    @Autowired
    private CheckRoleUtil checkRoleUtil;


    @Override
    public boolean addArt(Art art) {

        checkAddArt(art);
        art.setStatus("草稿");
        if(StrUtil.isEmpty(art.getArtOrigin()) || StrUtil.isBlank(art.getArtOrigin())){
            art.setArtOrigin("");
        }
        if(StrUtil.isEmpty(art.getSecondaryDiscipline()) || StrUtil.isBlank(art.getSecondaryDiscipline())){
            art.setSecondaryDiscipline("");
        }

        art.setEnteredDate(LocalDateTime.now());

        return baseMapper.insert(art) == 1;
    }

    @Override
    public boolean deleteArt(String artId) throws IOException {

        // 校验普通用户权限不能修改当前状态信息
        Art art = super.getOne(Wrappers.lambdaQuery(Art.class)
                .eq(Art::getArtID, artId));
        checkRoleUtil.checkPermissionAchievement(art.getStatus());

        // 删除艺术关联的作者根据艺术id
        artauthorService.remove(Wrappers.lambdaQuery(Art_author.class)
                .eq(Art_author::getArtID, artId));

        // 删除艺术关联的文件信息根据艺术id
        artfileService.remove(Wrappers.lambdaQuery(Artfile.class)
                .eq(Artfile::getArtid, artId));

        // 删除艺术关联的量化分数根据艺术id
        artQualificationService.remove(Wrappers.lambdaQuery(Art_Qualification.class)
                .eq(Art_Qualification::getArtID, artId));

        // 删除文件信息
        List<Artfile> artFiles = artfileService.list(Wrappers.lambdaQuery(Artfile.class)
                .eq(Artfile::getArtid, artId));
        List<String> fileIds = artFiles.stream()
                .map(Artfile::getFileid)
                .collect(Collectors.toList());
        for (String fileId : fileIds) {
            artfileService.deletArtfile(fileId);
        }
        // 删除审核记录根据艺术ID
        auditService.remove(Wrappers.lambdaQuery(Audit.class)
                .eq(Audit::getSynthesisID, artId));

        // 最后删除艺术本身
        return baseMapper.deleteById(artId) == 1;

    }

    @Override
    public boolean updateArt(Art art) {
        checkRoleUtil.checkPermissionAchievement(art.getStatus());
        checkupdateArt(art);
        Art one = iArtService.getOne(Wrappers.lambdaQuery(Art.class)
                .eq(Art::getArtName, art.getArtName())
                .ne(Art::getArtID, art.getArtID()));

        if(Objects.nonNull(one)){
            throw new BaseException("该艺术类型名称已存在!");
        }

        return baseMapper.updateById(art)==1;
    }


    @Override
    public boolean checkArtname(String name) {
        Art one = super.getOne(Wrappers.lambdaQuery(Art.class)
                .eq(Art::getArtName, name));
        if(Objects.nonNull(one)){
            throw new BaseException("该艺术作品名称已存在!");
        }
        return true;
    }


    @Override
    public Art getArt(String aid) {
        Art art = super.getOne(Wrappers.lambdaQuery(Art.class)
                .eq(Art::getArtID, aid));
        if(Objects.isNull(art)){
            throw new BaseException("论文编号异常!未查找到该论文");
        }
        return art;
    }

    @Override
    public ArtDTO getArtDTOByID(String aid) {
        Art art = super.getOne(Wrappers.lambdaQuery(Art.class)
                .eq(Art::getArtID, aid));
        if(Objects.isNull(art)){
            throw new BaseException("论文编号异常!未查找到该论文");
        }
        String entered = idToStatsService.IdToName(art.getEntered());
        String dept=idToStatsService.IdToDept(art.getDept());
        String allAuthor=idToStatsService.IdToAllauthor(art.getAllAuthor());

        ArtDTO artdto = new ArtDTO();
        BeanUtils.copyProperties(art,artdto);

        artdto.setAllAuthorName(allAuthor);
        artdto.setEnteredName(entered);
        artdto.setDeptName(dept);
        
        return artdto;
    }

    /**
     * 艺术作品院级审核通过
     * @param token
     * @param artId
     * @return
     */
    @Override
    public Boolean collegeCheckPass(String token, String artId) {
        Art art = query().eq("ArtID", artId).one();
        if (art == null) throw new BaseException("该艺术作品编号有误!");

        if (!StatusCheckConstant.WAIT_COLLEGE_CHECK.equals(art.getStatus())) {
            throw new BaseException("该艺术作品状态不处于该环节!");
        }

        String roleName = userInfoUtils.getCurrentUserInfo().getRoleName();

        String targetStatus = StatusCheckConstant.COLLEGE_CHECK_PEOPLE.equals(roleName)
                ? StatusCheckConstant.WAIT_SCHOOL_CHECK
                : StatusCheckConstant.CHECK_PASS;

        return checkAuditHelper.doPassAudit(
                art,
                StatusCheckConstant.WAIT_COLLEGE_CHECK,
                targetStatus,
                roleName,
                "艺术作品",
                art::getArtID,
                art::getStatus,
                art::setStatus,
                this::updateArtByEntity
        );
    }

    /**
     * 艺术作品院级审核退回
     * @param token
     * @param checkBackDTO
     * @return
     */
    @Override
    public Boolean collegeCheckBack(String token, CheckBackDTO checkBackDTO) {
        Art art = query().eq("ArtID", checkBackDTO.getID()).one();
        if (art == null) throw new BaseException("该艺术作品编号有误!");

        if (!StatusCheckConstant.WAIT_COLLEGE_CHECK.equals(art.getStatus())) {
            throw new BaseException("该艺术作品状态不处于该环节!");
        }

        String roleName = userInfoUtils.getCurrentUserInfo().getRoleName();
        String backStatus = StatusCheckConstant.COLLEGE_CHECK_PEOPLE.equals(roleName)
                ? StatusCheckConstant.COLLEGE_CHECK_BACK
                : StatusCheckConstant.SCHOOL_CHECK_BACK;

        return checkAuditHelper.doBackAudit(
                art,
                StatusCheckConstant.WAIT_COLLEGE_CHECK,
                backStatus,
                checkBackDTO.getReason(),
                "艺术作品",
                art::getArtID,
                art::getStatus,
                art::setStatus,
                art::setReason,
                this::updateArtByEntity
        );
    }

    /**
     * 艺术作品校级审核通过
     * @param token
     * @param artId
     * @return
     */
    @Override
    public Boolean schoolCheckPass(String token, String artId) {
        Art art = query().eq("ArtID", artId).one();
        if (art == null) throw new BaseException("该艺术作品编号有误!");

        String currentStatus = art.getStatus();
        if (!StatusCheckConstant.WAIT_SCHOOL_CHECK.equals(currentStatus)
                && !StatusCheckConstant.WAIT_COLLEGE_CHECK.equals(currentStatus)) {
            throw new BaseException("该艺术作品状态不处于该环节!");
        }


        String roleName = userInfoUtils.getCurrentUserInfo().getRoleName();

        return checkAuditHelper.doPassAudit(
                art,
                currentStatus,
                StatusCheckConstant.CHECK_PASS,
                roleName,
                "艺术作品",
                art::getArtID,
                art::getStatus,
                art::setStatus,
                this::updateArtByEntity
        );
    }

    /**
     * 艺术作品校级审核退回
     * @param token
     * @param checkBackDTO
     * @return
     */
    @Override
    public Boolean schoolCheckBack(String token, CheckBackDTO checkBackDTO) {
        Art art = query().eq("ArtID", checkBackDTO.getID()).one();
        if (art == null) throw new BaseException("该艺术作品编号有误!");

        String currentStatus = art.getStatus();
        if (!StatusCheckConstant.WAIT_SCHOOL_CHECK.equals(currentStatus)
                && !StatusCheckConstant.WAIT_COLLEGE_CHECK.equals(currentStatus)
                && !StatusCheckConstant.CHECK_PASS.equals(currentStatus)) {
            throw new BaseException("该艺术作品状态不处于该环节!");
        }

        String roleName = userInfoUtils.getCurrentUserInfo().getRoleName();

        return checkAuditHelper.doBackAudit(
                art,
                currentStatus,
                StatusCheckConstant.SCHOOL_CHECK_BACK,
                checkBackDTO.getReason(),
                "艺术作品",
                art::getArtID,
                art::getStatus,
                art::setStatus,
                art::setReason,
                this::updateArtByEntity
        );
    }

    /**
     * 更新艺术作品实体
     */
    private Boolean updateArtByEntity(Art art) {
        return baseMapper.updateById(art) == 1;
    }


    @Override
    public Boolean withdrawArt(String id) {
        // 获取当前用户ID
        String userId = BaseContext.getCurrentId();
        User user = iUserService.getById(userId);
        if (user == null) {
            throw new BaseException("用户不存在");
        }
        
        // 查询艺术作品信息
        Art art = super.getOne(Wrappers.lambdaQuery(Art.class).eq(Art::getArtID, id));
        if (art == null) {
            throw new BaseException("艺术作品不存在");
        }
        
        // 检查状态是否为院级审核中
        if (!StatusCheckConstant.WAIT_COLLEGE_CHECK.equals(art.getStatus())) {
            throw new BaseException("只有院级审核中的艺术作品可以撤回");
        }
        
        // 将状态更新为草稿
        art.setStatus(StatusCheckConstant.DRAFT);
        
        return baseMapper.updateById(art) == 1;
    }
    
    @Override
    public Boolean ReCommitArt(String id) {
        Art art = super.getOne(Wrappers.lambdaQuery(Art.class).eq(Art::getArtID,id));
        checkCommitField(art);
        art.setStatus("待院级审核");
        art.setReason("");

        return baseMapper.updateById(art)==1;
    }

    @Override
    public CommonPage<ArtVO> userGetRelateArt(ArtPageQuery artPageQuery) {

        String userId = BaseContext.getCurrentId();
        User user = iUserService.getById(userId);
        System.out.println("用户id:"+userId);
        System.out.println("用户id:"+user);
        String role = user.getRole();
        System.out.println("用户角色:"+role);

        // 创建MyBatis-Plus的Page对象
        Page<ArtVO> page = new Page<>(artPageQuery.getPageNum(), artPageQuery.getPageSize());
        IPage<ArtVO> artIPage = null;
        // 根据角色执行不同查询
        if (role.equals(RoleConstant.ROLE_ADMIN_SCHOOL)) {
            artIPage = artMapper.schoolGetRelateArtQuery(page, artPageQuery, user);
        } else if (role.equals(RoleConstant.ROLE_ADMIN_COLLEGE)) {
            artIPage = artMapper.collegeGetRelateArtQuery(page, artPageQuery, user);
        } else {
            System.out.println("============================");
            artIPage = artMapper.userGetRelateArtQuery(page, artPageQuery, user);
        }
        // 初始化量化分数
        float figure = 0;

        //查询专利关联的作者
        // 遍历记录，计算量化分数
        List<ArtVO> records = artIPage.getRecords();
        for (ArtVO record : records) {
            if (record.getStatus().equals("审核通过")){
                figure += record.getScore();
            }
        }

        // 构造返回分页对象
        CommonPage<ArtVO> artCommonPage = CommonPage.restPage(artIPage);

        artCommonPage.setFigure(figure);
        artCommonPage.setList(records);


        return artCommonPage;

    }


    @Override
    public CommonPage<Art> export(ArtPageQuery artPageQuery){
        String userId = BaseContext.getCurrentId();
        User user = iUserService.getById(userId);
        String role = user.getRole();

        Page<Art> page = new Page<>(artPageQuery.getPageNum(), artPageQuery.getPageSize());
        IPage<Art> artIPage;

        if (RoleConstant.ROLE_ADMIN_SCHOOL.equals(role)) {
            artIPage = artMapper.schoolExportRelateArtQuery(page, artPageQuery, user);
        } else if (RoleConstant.ROLE_ADMIN_COLLEGE.equals(role)) {
            artIPage = artMapper.collegeExportRelateArtQuery(page, artPageQuery, user);
        } else {
            artIPage = artMapper.userExportRelateArtQuery(page, artPageQuery, user);
        }

        List<Art> records = artIPage.getRecords();

        float figure = 0;
        for (Art record : records) {
            if (StatusCheckConstant.CHECK_PASS.equals(record.getStatus())) {
                figure += Float.parseFloat(record.getScore() != null ? record.getScore() : "0");
            }
            User userInfo = iUserService.getById(record.getEntered());
            record.setEntered(userInfo.getName());

            // 查询第一作者/共同第一作者
            List<Art_author> leadAuthors = artauthorService.list(Wrappers.lambdaQuery(Art_author.class)
                    .eq(Art_author::getArtID, record.getArtID())
                    .in(Art_author::getAuthortype, Arrays.asList("第一作者", "共同第一作者")));
            record.setLeadAuthor(leadAuthors.stream().map(Art_author::getName).collect(Collectors.joining(",")));

            // 查询通讯作者
            List<Art_author> contactAuthors = artauthorService.list(Wrappers.lambdaQuery(Art_author.class)
                    .eq(Art_author::getArtID, record.getArtID())
                    .eq(Art_author::getAuthortype, "通讯作者"));
            record.setCorrespondingAuthor(contactAuthors.stream().map(Art_author::getName).collect(Collectors.joining(",")));

            List<Art_author> art_authors = artauthorService.listAuthor(record.getArtID());
            String authorNames = art_authors == null ? "" :
                    art_authors.stream()
                            // 过滤掉列表中可能存在的null对象
                            .filter(Objects::nonNull)
                            // 提取每个作者的name字段
                            .map(Art_author::getName)
                            // 过滤掉name为null的情况
                            .filter(Objects::nonNull)
                            // 用逗号拼接所有name
                            .collect(Collectors.joining(","));
            record.setAllAuthor(authorNames);

            String deptName = idToStatsService.IdToDept(record.getDept());
            record.setDept(deptName);
        }

        CommonPage<Art> artCommonPage = CommonPage.restPage(artIPage);
        artCommonPage.setFigure(figure);
        artCommonPage.setList(records);
        return artCommonPage;
    }

    private void checkAddArt(Art art){
        if(StrUtil.isEmpty(art.getArtName()) || StrUtil.isBlank(art.getArtName())){
            throw new BaseException("请输入作品名称");
        }
        if(StrUtil.isEmpty(art.getArtType()) || StrUtil.isBlank(art.getArtType())){
            throw new BaseException("请输入作品类型");
        }
        if(StrUtil.isEmpty(art.getArtType()) || StrUtil.isBlank(art.getArtType())){
            throw new BaseException("请输入作品类型");
        }
        if(StrUtil.isEmpty(art.getArtRewardCate()) || StrUtil.isBlank(art.getArtRewardCate())){
            throw new BaseException("请输入作品获奖类别");
        }
        if(StrUtil.isEmpty(art.getArtRewardLevel()) || StrUtil.isBlank(art.getArtRewardLevel())){
            throw new BaseException("请输入作品获奖等级");
        }
        if(StrUtil.isEmpty(art.getResearchCate()) || StrUtil.isBlank(art.getResearchCate())){
            throw new BaseException("请输入研究类别");
        }
        if(StrUtil.isEmpty(art.getFirstDiscipline()) || StrUtil.isBlank(art.getFirstDiscipline())){
            throw new BaseException("请输入一级学科");
        }
        Art one1 = super.getOne(Wrappers.lambdaQuery(Art.class)
                .eq(Art::getArtName, art.getArtName()));
        if(Objects.nonNull(one1) && !(one1.getArtID().equals(art.getArtID()))){
            throw new BaseException("艺术作品名称重复!");
        }
    }


    private void checkupdateArt(Art art){
        if(StrUtil.isEmpty(art.getArtName()) || StrUtil.isBlank(art.getArtName())){
            throw new BaseException("请输入作品名称");
        }
        if(StrUtil.isEmpty(art.getArtType()) || StrUtil.isBlank(art.getArtType())){
            throw new BaseException("请输入作品类型");
        }
        if(StrUtil.isEmpty(art.getArtType()) || StrUtil.isBlank(art.getArtType())){
            throw new BaseException("请输入作品类型");
        }
        if(StrUtil.isEmpty(art.getArtRewardCate()) || StrUtil.isBlank(art.getArtRewardCate())){
            throw new BaseException("请输入作品获奖类别");
        }
        if(StrUtil.isEmpty(art.getArtRewardLevel()) || StrUtil.isBlank(art.getArtRewardLevel())){
            throw new BaseException("请输入作品获奖等级");
        }
        if(StrUtil.isEmpty(art.getResearchCate()) || StrUtil.isBlank(art.getResearchCate())){
            throw new BaseException("请输入研究类别");
        }
        if(StrUtil.isEmpty(art.getFirstDiscipline()) || StrUtil.isBlank(art.getFirstDiscipline())){
            throw new BaseException("请输入一级学科");
        }
    }

    private void checkCommitField(Art art){

        if(Objects.isNull(art)){
            throw new BaseException("论文编号有误!");
        }
        if(!art.getStatus().equals("草稿") && !art.getStatus().equals("被院级退回") && !art.getStatus().equals("被校级退回")){
            throw new BaseException("该论文不适用于该阶段!");
        }
        if(StrUtil.isEmpty(art.getArtName()) || StrUtil.isBlank(art.getArtName())){
            throw new BaseException("请输入作品名称");
        }
        if(StrUtil.isEmpty(art.getArtType()) || StrUtil.isBlank(art.getArtType())){
            throw new BaseException("请输入作品类型");
        }
        if(StrUtil.isEmpty(art.getArtType()) || StrUtil.isBlank(art.getArtType())){
            throw new BaseException("请输入作品类型");
        }
        if(StrUtil.isEmpty(art.getArtRewardCate()) || StrUtil.isBlank(art.getArtRewardCate())){
            throw new BaseException("请输入作品获奖类别");
        }
        if(StrUtil.isEmpty(art.getArtRewardLevel()) || StrUtil.isBlank(art.getArtRewardLevel())){
            throw new BaseException("请输入作品获奖等级");
        }
        if(StrUtil.isEmpty(art.getResearchCate()) || StrUtil.isBlank(art.getResearchCate())){
            throw new BaseException("请输入研究类别");
        }
        if(StrUtil.isEmpty(art.getFirstDiscipline()) || StrUtil.isBlank(art.getFirstDiscipline())){
            throw new BaseException("请输入一级学科");
        }
        
        // 检查量化分数是否填写
        Art_Qualification qualification = artQualificationService.getOne(
                Wrappers.lambdaQuery(Art_Qualification.class)
                        .eq(Art_Qualification::getArtID, art.getArtID())
        );
        if (Objects.isNull(qualification)) {
            throw new BaseException("请先填写艺体作品的量化分数!");
        }
        
        // 检查作者列表是否填写
        List<Art_author> authorList = artauthorService.list(
                Wrappers.lambdaQuery(Art_author.class)
                        .eq(Art_author::getArtID, art.getArtID())
        );
        if (CollectionUtils.isEmpty(authorList)) {
            throw new BaseException("请先添加艺体作品的作者信息!");
        }
    }

}
